home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / des_pc.arc / DES_PC.C next >
Text File  |  1986-03-12  |  24KB  |  747 lines

  1. /* des: duplicate the NBS Data Encryption Standard in software.
  2.  * usage: des <file> [more files . . .]
  3.  * prompts for the password.
  4.  * prompts for encryption or decryption.
  5.  *
  6.  * Permutation algorithm:
  7.  *    The permutation is defined by its effect on each of the 16 nibbles
  8.  *    of the 64-bit input.  For each nibble we give an 8-byte bit array
  9.  *    that has the bits in the input nibble distributed correctly.  The
  10.  *    complete permutation involves ORing the 16 sets of 8 bytes designated
  11.  *    by the 16 input nibbles.  Uses 16*16*8 = 2K bytes of storage for
  12.  *    each 64-bit permutation.  32-bit permutations (P) and expansion (E)
  13.  *    are done similarly, but using bytes instead of nibbles.
  14.  *    Should be able to use long ints, adding the masks, at a
  15.  *    later pass.  Tradeoff: can speed 64-bit perms up at cost of slowing 
  16.  *    down expansion or contraction operations by using 8K tables here and
  17.  *    decreasing the size of the other tables.
  18.  * The compressions are pre-computed in 12-bit chunks, combining 2 of the
  19.  *    6->4 bit compressions.
  20.  * The key schedule is also precomputed.
  21.  * Compile with VALIDATE defined to run the NBS validation suite.
  22.  *
  23.  * Jim Gillogly, May 1977
  24.  * Modified 8/84 by Jim Gillogly and Lauren Weinstein to compile with
  25.  *   post-1977 C compilers and systems
  26.  * Modified slightly 2/86 by Michael Silvan.
  27.  *
  28.  * This program is now officially in the public domain, and is available for
  29.  * any non-profit use as long as the authorship line is retained.
  30.  */
  31.  
  32. /*#define VALIDATE    */    /* define to check the NBS validation suite */
  33. /*#define DEBUG     */
  34. #define LATTICE                /* define for Lattice C on IBM PC */
  35.  
  36. #include <stdio.h>
  37.  
  38. #ifndef LATTICE
  39. #include <sgtty.h>
  40. #include <signal.h>
  41. #include <sys/types.h>  /* for local timer */
  42. #include <sys/timeb.h>  /* ditto */
  43.  
  44. struct sgttyb ttybuf;            /* for gtty/stty         */
  45. int bye();                /* for caught interrupts     */
  46.  
  47. #endif
  48.  
  49. char iperm[16][16][8],fperm[16][16][8]; /* inital and final permutations*/
  50. char s[4][4096];            /* S1 thru S8 precomputed    */
  51. char p32[4][256][4];            /* for permuting 32-bit f output*/
  52. char kn[16][6];                /* key selections        */
  53.  
  54. endes(inblock,outblock)            /* encrypt 64-bit inblock    */
  55. char *inblock, *outblock;
  56. {    char iters[17][8];        /* workspace for each iteration */
  57.     char swap[8];            /* place to interchange L and R */
  58.     register int i;
  59.     register char *s, *t;
  60.  
  61.     permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  62.     for (i=0; i<16; i++)        /* 16 churning operations    */
  63.         iter(i,iters[i],iters[i+1]);
  64.                     /* don't re-copy to save space  */
  65.     s = swap; t = &iters[16][4];    /* interchange left        */
  66.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  67.     t = &iters[16][0];        /* and right            */
  68.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  69.     permute(swap,fperm,outblock);   /* apply final permutation    */
  70. }
  71.  
  72. dedes(inblock,outblock)            /* decrypt 64-bit inblock    */
  73. char *inblock,*outblock;
  74. {    char iters[17][8];        /* workspace for each iteration */
  75.     char swap[8];            /* place to interchange L and R */
  76.     register int i;
  77.     register char *s, *t;
  78.  
  79.     permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  80.     for (i=0; i<16; i++)        /* 16 churning operations    */
  81.         iter(15-i,iters[i],iters[i+1]);
  82.                     /* reverse order from encrypting*/
  83.     s = swap; t = &iters[16][4];    /* interchange left        */
  84.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  85.     t = &iters[16][0];        /* and right            */
  86.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  87.     permute(swap,fperm,outblock);   /* apply final permutation    */
  88. }
  89.  
  90. permute(inblock,perm,outblock)        /* permute inblock with perm    */
  91. char *inblock, *outblock;        /* result into outblock,64 bits */
  92. char perm[16][16][8];            /* 2K bytes defining perm.    */
  93. {    register int i,j;
  94.     register char *ib, *ob;        /* ptr to input or output block */
  95.     register char *p, *q;
  96.  
  97.     for (i=0, ob = outblock; i<8; i++)
  98.         *ob++ = 0;        /* clear output block        */
  99.     ib = inblock;
  100.     for (j = 0; j < 16; j += 2, ib++) /* for each input nibble    */
  101.     {    ob = outblock;
  102.         p = perm[j][(*ib >> 4) & 017];
  103.         q = perm[j + 1][*ib & 017];
  104.         for (i = 0; i < 8; i++)   /* and each output byte    */
  105.             *ob++ |= *p++ | *q++;   /* OR the masks together*/
  106.     }
  107. }
  108.  
  109. char ip[]                /* initial permutation P    */
  110. = {    58, 50, 42, 34, 26, 18, 10,  2,
  111.     60, 52, 44, 36, 28, 20, 12,  4,
  112.     62, 54, 46, 38, 30, 22, 14,  6,
  113.     64, 56, 48, 40, 32, 24, 16,  8,
  114.     57, 49, 41, 33, 25, 17,  9,  1,
  115.     59, 51, 43, 35, 27, 19, 11,  3,
  116.     61, 53, 45, 37, 29, 21, 13,  5,
  117.     63, 55, 47, 39, 31, 23, 15,  7    };
  118.  
  119. char fp[]                /* final permutation F      */
  120. = {    40,  8, 48, 16, 56, 24, 64, 32,
  121.     39,  7, 47, 15, 55, 23, 63, 31,
  122.     38,  6, 46, 14, 54, 22, 62, 30,
  123.     37,  5, 45, 13, 53, 21, 61, 29,
  124.     36,  4, 44, 12, 52, 20, 60, 28,
  125.     35,  3, 43, 11, 51, 19, 59, 27,
  126.     34,  2, 42, 10, 50, 18, 58, 26,
  127.     33,  1, 41,  9, 49, 17, 57, 25    };
  128.  
  129. /* expansion operation matrix   */    /* rwo: unused    */
  130. /* char ei[] = {    32,  1,  2,  3,  4,  5,
  131.      4,  5,  6,  7,  8,  9,
  132.      8,  9, 10, 11, 12, 13,
  133.     12, 13, 14, 15, 16, 17,
  134.     16, 17, 18, 19, 20, 21,
  135.     20, 21, 22, 23, 24, 25,
  136.     24, 25, 26, 27, 28, 29,
  137.     28, 29, 30, 31, 32,  1  };    */
  138.  
  139. char pc1[]                /* permuted choice table (key)  */
  140. = {    57, 49, 41, 33, 25, 17,  9,
  141.      1, 58, 50, 42, 34, 26, 18,
  142.     10,  2, 59, 51, 43, 35, 27,
  143.     19, 11,  3, 60, 52, 44, 36,
  144.  
  145.     63, 55, 47, 39, 31, 23, 15,
  146.      7, 62, 54, 46, 38, 30, 22,
  147.     14,  6, 61, 53, 45, 37, 29,
  148.     21, 13,  5, 28, 20, 12,  4    };
  149.  
  150. char totrot[]               /* number left rotations of pc1 */
  151. = {    1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28    };
  152.  
  153. char pc1m[56];              /* place to modify pc1 into    */
  154. char pcr[56];               /* place to rotate pc1 into    */
  155.  
  156. char pc2[]                /* permuted choice key (table)  */
  157. = {    14, 17, 11, 24,  1,  5,
  158.      3, 28, 15,  6, 21, 10,
  159.     23, 19, 12,  4, 26,  8,
  160.     16,  7, 27, 20, 13,  2,
  161.     41, 52, 31, 37, 47, 55,
  162.     30, 40, 51, 45, 33, 48,
  163.     44, 49, 39, 56, 34, 53,
  164.     46, 42, 50, 36, 29, 32    };
  165.  
  166. char si[8][64]              /* 48->32 bit compression tables*/
  167. = {                    /* S[1]             */
  168.     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  169.      0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  170.      4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  171.     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  172.                     /* S[2]             */
  173.     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  174.      3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  175.      0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  176.     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  177.                     /* S[3]             */
  178.     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  179.     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  180.     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  181.      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  182.                     /* S[4]             */
  183.      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  184.     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  185.     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  186.      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  187.                     /* S[5]             */
  188.      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  189.     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  190.      4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  191.     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  192.                     /* S[6]             */
  193.     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  194.     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  195.      9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  196.      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  197.                     /* S[7]             */
  198.      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  199.     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  200.      1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  201.      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  202.                     /* S[8]             */
  203.     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  204.      1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  205.      7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  206.      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    };
  207.  
  208. char p32i[]                /* 32-bit permutation function  */
  209. = {    16,  7, 20, 21,
  210.     29, 12, 28, 17,
  211.      1, 15, 23, 26,
  212.      5, 18, 31, 10,
  213.      2,  8, 24, 14,
  214.     32, 27,  3,  9,
  215.     19, 13, 30,  6,
  216.     22, 11,  4, 25    };
  217.  
  218. desinit(key)                /* initialize all des arrays    */
  219. char *key;
  220. {
  221. #ifdef DEBUG
  222. /*deb*/ printf("Initial perm init.\n");
  223. #endif
  224.     perminit(iperm,ip);        /* initial permutation        */
  225. #ifdef DEBUG
  226. /*deb*/ printf("Final perm init.\n");
  227. #endif
  228.     perminit(fperm,fp);        /* final permutation        */
  229. #ifdef DEBUG
  230. /*deb*/ printf("Key sched init.\n");
  231. #endif
  232.     kinit(key);            /* key schedule            */
  233. #ifdef DEBUG
  234. /*deb*/ printf("Compression init.\n");
  235. #endif
  236.     sinit();            /* compression functions    */
  237.  
  238. #ifdef DEBUG
  239. /*deb*/ printf("32-bit perm init.\n");
  240. #endif
  241.     p32init();            /* 32-bit permutation in f    */
  242. #ifdef DEBUG
  243. /*deb*/ printf("End init.\n");
  244. #endif
  245. }
  246.  
  247. int bytebit[]               /* bit 0 is left-most in byte    */
  248.     = {    0200,0100,040,020,010,04,02,01 };
  249.  
  250. int nibblebit[] = { 010,04,02,01 };
  251.  
  252. sinit()                 /* initialize s1-s8 arrays        */
  253. {    register int i,j;
  254.  
  255.     for (i=0; i<4; i++)        /* each 12-bit position        */
  256.         for (j=0; j<4096; j++)  /* each possible 12-bit value   */
  257.             s[i][j]=(getcomp(i*2,j>>6)<<4) |
  258.                 (017&getcomp(i*2+1,j&077));
  259.                     /* store 2 compressions per char*/
  260. }
  261.  
  262. getcomp(k,v)                /* 1 compression value for sinit*/
  263. int k,v;
  264. {    register int i,j;        /* correspond to i and j in FIPS*/
  265.  
  266.     i=((v&040)>>4)|(v&1);        /* first and last bits make row */
  267.     j=(v&037)>>1;            /* middle 4 bits are column    */
  268.     return (int) si[k][(i<<4)+j];   /* result is ith row, jth col   */
  269. }
  270.  
  271. kinit(key)                /* initialize key schedule array*/
  272. char *key;                /* 64 bits (will use only 56)   */
  273. {    register int i,j,l;
  274.     int m;
  275.  
  276.     for (j=0; j<56; j++)        /* convert pc1 to bits of key   */
  277.     {    l=pc1[j]-1;        /* integer bit location        */
  278.         m = l & 07;        /* find bit            */
  279.         pc1m[j]=(key[l>>3] &    /* find which key byte l is in  */
  280.             bytebit[m])    /* and which bit of that byte   */
  281.             ? 1 : 0;    /* and store 1-bit result    */
  282.     }
  283.     for (i=0; i<16; i++)        /* for each key sched section   */
  284.         for (j=0; j<6; j++)    /* and each byte of the kn    */
  285.             kn[i][j]=0;    /* clear it for accumulation    */
  286.     for (i=0; i<16; i++)        /* key chunk for each iteration */
  287.     {    for (j=0; j<56; j++)    /* rotate pc1 the right amount  */
  288.         pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  289.             /* rotate left and right halves independently   */
  290.         for (j=0; j<48; j++)    /* select bits individually    */
  291.         if (pcr[pc2[j]-1])    /* check bit that goes to kn[j] */
  292.             {    l= j & 07;
  293.                 kn[i][j>>3] |= bytebit[l];
  294.             }        /* mask it in if it's there    */
  295.     }
  296. }
  297.  
  298. p32init()                /* initialize 32-bit permutation*/
  299. {    register int l, j, k;
  300.     int i,m;
  301.  
  302.     for (i=0; i<4; i++)        /* each input byte position    */
  303.         for (j=0; j<256; j++)    /* all possible input bytes    */
  304.         for (k=0; k<4; k++)    /* each byte of the mask    */
  305.             p32[i][j][k]=0;    /* clear permutation array    */
  306.     for (i=0; i<4; i++)        /* each input byte position    */
  307.         for (j=0; j<256; j++)    /* each possible input byte    */
  308.         for (k=0; k<32; k++)    /* each output bit position    */
  309.         {   l=p32i[k]-1;    /* invert this bit (0-31)    */
  310.             if ((l>>3)!=i)    /* does it come from input posn?*/
  311.             continue;    /* if not, bit k is 0        */
  312.             if (!(j&bytebit[l&07]))
  313.             continue;    /* any such bit in input?    */
  314.             m = k & 07;     /* which bit is it?        */
  315.             p32[i][j][k>>3] |= bytebit[m];
  316.         }
  317. }
  318.  
  319. perminit(perm,p)            /* initialize a perm array    */
  320. char perm[16][16][8];            /* 64-bit, either init or final */
  321. char p[64];
  322. {    register int l, j, k;
  323.     int i,m;
  324.  
  325.     for (i=0; i<16; i++)        /* each input nibble position   */
  326.         for (j=0; j<16; j++)    /* all possible input nibbles   */
  327.         for (k=0; k<8; k++)    /* each byte of the mask    */
  328.             perm[i][j][k]=0;/* clear permutation array    */
  329.     for (i=0; i<16; i++)        /* each input nibble position   */
  330.         for (j = 0; j < 16; j++)/* each possible input nibble   */
  331.         for (k = 0; k < 64; k++)/* each output bit position    */
  332.         {   l = p[k] - 1;    /* where does this bit come from*/
  333.             if ((l >> 2) != i)  /* does it come from input posn?*/
  334.             continue;    /* if not, bit k is 0        */
  335.             if (!(j & nibblebit[l & 3]))
  336.             continue;    /* any such bit in input?    */
  337.             m = k & 07;    /* which bit is this in the byte*/
  338.             perm[i][j][k>>3] |= bytebit[m];
  339.         }
  340. }
  341.  
  342. iter(num,inblock,outblock)        /* 1 churning operation        */
  343. int num;                /* i.e. the num-th one        */
  344. char *inblock, *outblock;        /* 64 bits each            */
  345. {    char fret[4];            /* return from f(R[i-1],key)    */
  346.     register char *ib, *ob, *fb;
  347. /*    register int i;    */    /* rwo: unused    */
  348.  
  349.     ob = outblock; ib = &inblock[4];
  350.     f(ib, num, fret);        /* the primary transformation   */
  351.     *ob++ = *ib++;            /* L[i] = R[i-1]        */
  352.     *ob++ = *ib++;
  353.     *ob++ = *ib++;
  354.     *ob++ = *ib++;
  355.     ib = inblock; fb = fret;    /* R[i]=L[i] XOR f(R[i-1],key)  */
  356.     *ob++ = *ib++ ^ *fb++;
  357.     *ob++ = *ib++ ^ *fb++;
  358.     *ob++ = *ib++ ^ *fb++;
  359.     *ob++ = *ib++ ^ *fb++;
  360. }
  361.  
  362. f(right,num,fret)            /* critical cryptographic trans */
  363. char *right, *fret;            /* 32 bits each            */
  364. int num;                /* index number of this iter    */
  365. {    register char *kb, *rb, *bb;    /* ptr to key selection &c    */
  366.     char bigright[6];        /* right expanded to 48 bits    */
  367.     char result[6];            /* expand(R) XOR keyselect[num] */
  368.     char preout[4];            /* result of 32-bit permutation */
  369.  
  370.     kb = kn[num];            /* fast version of iteration    */
  371.     bb = bigright;
  372.     rb = result;
  373.     expand(right,bb);        /* expand to 48 bits        */
  374.     *rb++ = *bb++ ^ *kb++;        /* expanded R XOR chunk of key  */
  375.     *rb++ = *bb++ ^ *kb++;
  376.     *rb++ = *bb++ ^ *kb++;
  377.     *rb++ = *bb++ ^ *kb++;
  378.     *rb++ = *bb++ ^ *kb++;
  379.     *rb++ = *bb++ ^ *kb++;
  380.     contract(result,preout);    /* use S fns to get 32 bits    */
  381.     perm32(preout,fret);        /* and do final 32-bit perm    */
  382. }
  383.  
  384. perm32(inblock,outblock)        /* 32-bit permutation at end    */
  385. char *inblock,*outblock;        /* of the f crypto function    */
  386. {    register int j;
  387. /*    register int i;    */    /* rwo: unused    */
  388.     register char *ib, *ob;
  389.     register char *q;
  390.  
  391.     ob = outblock;            /* clear output block        */
  392.     *ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
  393.     ib=inblock;            /* ptr to 1st byte of input    */
  394.     for (j=0; j<4; j++, ib++)    /* for each input byte        */
  395.     {    q = p32[j][*ib & 0377];
  396.         ob = outblock;        /* and each output byte        */
  397.         *ob++ |= *q++;        /* OR the 16 masks together    */
  398.         *ob++ |= *q++;
  399.         *ob++ |= *q++;
  400.         *ob++ |= *q++;
  401.     }
  402. }
  403.  
  404. expand(right,bigright)            /* 32 to 48 bits with E oper    */
  405. char *right,*bigright;            /* right is 32, bigright 48    */
  406. {
  407.     register char *bb, *r, r0, r1, r2, r3;
  408.  
  409.     bb = bigright;
  410.     r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
  411.     *bb++ = ((r3 & 0001) << 7) |    /* 32                */
  412.         ((r0 & 0370) >> 1) |    /* 1 2 3 4 5            */
  413.         ((r0 & 0030) >> 3);    /* 4 5                */
  414.     *bb++ = ((r0 & 0007) << 5) |    /* 6 7 8            */
  415.         ((r1 & 0200) >> 3) |    /* 9                */
  416.         ((r0 & 0001) << 3) |    /* 8                */
  417.         ((r1 & 0340) >> 5);    /* 9 10 11            */
  418.     *bb++ = ((r1 & 0030) << 3) |    /* 12 13            */
  419.         ((r1 & 0037) << 1) |    /* 12 13 14 15 16        */
  420.         ((r2 & 0200) >> 7);    /* 17                */
  421.     *bb++ = ((r1 & 0001) << 7) |    /* 16                */
  422.         ((r2 & 0370) >> 1) |    /* 17 18 19 20 21        */
  423.         ((r2 & 0030) >> 3);    /* 20 21            */
  424.     *bb++ = ((r2 & 0007) << 5) |    /* 22 23 24            */
  425.         ((r3 & 0200) >> 3) |    /* 25                */
  426.         ((r2 & 0001) << 3) |    /* 24                */
  427.         ((r3 & 0340) >> 5);    /* 25 26 27            */
  428.     *bb++ = ((r3 & 0030) << 3) |    /* 28 29            */
  429.         ((r3 & 0037) << 1) |    /* 28 29 30 31 32        */
  430.         ((r0 & 0200) >> 7);    /* 1                */
  431. }
  432.  
  433. contract(in48,out32)            /* contract f from 48 to 32 bits*/
  434. char *in48,*out32;            /* using 12-bit pieces into bytes */
  435. {    register char *c;
  436.     register char *i;
  437.     register int i0, i1, i2, i3, i4, i5;
  438.  
  439.     i = in48;
  440.     i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
  441.     c = out32;            /* do output a byte at a time   */
  442.     *c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))];
  443.     *c++ = s[1][07777 & ((i1 << 8) | ( i2    & 0377 ))];
  444.     *c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))];
  445.     *c++ = s[3][07777 & ((i4 << 8) | ( i5    & 0377 ))];
  446. }
  447.  
  448. /* End of DES algorithm (except for calling desinit below)    */
  449.  
  450. #ifndef VALIDATE
  451. char *inname, *outname;
  452. FILE *infile, *outfile;
  453.  
  454. int encrypting;
  455. char buf[512];
  456. char keyx[9], keyy[9];
  457.  
  458. char *malloc(), *strcpy(), *strcat();
  459.  
  460. main(argc, argv)
  461. int argc; char *argv[];
  462. {    char *u;
  463.     char *filename,reply[200];
  464.         int ch;
  465.  
  466.     if (argc < 2)            /* filenames given? */
  467.     {  fprintf(stderr, "Usage: des <filename> [filename] ...\n");
  468.        exit(1);     
  469.     }
  470.  
  471.     for (++argv; --argc; ++argv)
  472.     {    inname = *argv;
  473.         outname = filename = malloc((unsigned) strlen(inname) + 4);
  474.         strcpy(filename, inname);
  475.                 if((u = strchr(filename,'.')) == NULL)
  476.                         u = &filename + strlen(filename) - 1;
  477.                 *u = 0;  /* terminate string */
  478.                 strcat(filename,".$$$"); /* make a temporary file */
  479.  
  480.                 for(;;) 
  481.                 {       printf("Do you want to decrypt or encrypt %s?(D or E):",inname);
  482.                         gets(reply);
  483.                         if(reply[0]!='d'&& reply[0]!='D'&& reply[0]!='e'&& reply[0]!='E')
  484.                                 continue;
  485.                         if(reply[0]=='e' || reply[0]=='E') encrypting = 1;
  486.                         else encrypting = 0;
  487.                         break;
  488.                 }
  489.  
  490.  
  491.         if ((infile = fopen(inname, "rb")) == NULL)
  492.         {    fprintf(stderr,"Can't read %s.\n", inname);
  493.             exit(1);
  494.         }
  495.         if ((outfile = fopen(outname, "rb")) != NULL)
  496.         {    fprintf(stderr, "%s would be overwritten.\n",outname);
  497.             exit(1);
  498.         }
  499.         if ((outfile = fopen(outname, "wb")) == NULL)
  500.         {    fprintf(stderr,"Can't write %s.\n", outname);
  501.             exit(1);
  502.         }
  503.  
  504.         key_get("Type password for ");
  505.         for (;;)
  506.         {    strcpy(keyx, keyy);
  507.             key_get("Verify password for ");
  508.             if (strcmp(keyx, keyy) == 0) break;
  509.         }
  510.         desinit(keyx);      /* set up tables for DES    */
  511.  
  512.         if (pfile() == 0) unlink(inname);
  513.         else    fprintf(stderr,
  514.                "%s: I/O Error -- File unchanged\n", inname);
  515.  
  516.         fclose(outfile);
  517.         fclose(infile);
  518.  
  519.  
  520.         if ((infile = fopen(outname, "rb")) == NULL)
  521.         {    fprintf(stderr,"Can't read %s.\n", inname);
  522.             exit(1);
  523.         }
  524.         if ((outfile = fopen(inname, "wb")) == NULL)
  525.         {    fprintf(stderr,"Can't write %s.\n", outname);
  526.             exit(1);
  527.         }
  528.  
  529.                 do
  530.                 {       ch = fgetc(infile);
  531.                         fputc(ch,outfile);
  532.                 }
  533.                 while(ch != EOF);
  534.  
  535.         fclose(outfile);
  536.         fclose(infile);
  537.                 remove(outname); /* get rid of temporary file */
  538.     }
  539.     exit(0);
  540. }
  541.  
  542. key_get(mes)            /* get file key */
  543. char *mes;
  544. {    register int i, j;
  545.     char linebuf[256];
  546.     int count;
  547.  
  548.     for (i=0; i<14; i++) keyy[i]=0;
  549.  
  550. #ifdef LATTICE
  551. #else
  552.     gtty(0, &ttybuf);
  553.     ttybuf.sg_flags &= ~ECHO;  /* turn off echoing */
  554.     signal(SIGINT, bye);    /* catch ints */
  555.     stty(0, &ttybuf);
  556. #endif
  557.  
  558.     printf("%s%s: ", mes, inname);
  559.     fflush(stdout);
  560.  
  561.     count = read(0, linebuf, 256);  /* read input line */
  562.     printf("\n");
  563.  
  564. #ifndef LATTICE
  565.     ttybuf.sg_flags |= ECHO;      /* restore echo */
  566.     stty(0, &ttybuf);
  567. #endif
  568.  
  569.     linebuf[count] = 0;  /* null terminate */
  570.     if (linebuf[count-1] == '\n')  /* ignore any terminating newline */
  571.     {  linebuf[count-1] = 0;
  572.        count--;     
  573.     }
  574.     if (count > 8) count = 8;    /* only use 8 chars */
  575.     for (i = j = 0; count--;)
  576.        keyy[i++] = linebuf[j++];
  577. }
  578.  
  579. pfile()                 /* process the file        */
  580. {    register int m, nsave;
  581.     register char *b;
  582.     int j;
  583.  
  584.     while (m = fread(buf, 1, 512, infile))
  585.     {
  586.         if ((nsave = m) < 0)    /* read error            */
  587.         return(-1);
  588.         for (b=buf; m>0;    /* encrypt/decrypt 1 buffer-full*/
  589.         m -= 8, b += 8)        /* 8-byte blocks        */
  590.         {   if (encrypting)
  591.         {   if (m<8)        /* don't have a full 64 bits    */
  592.             {   for (j=0; j<8-m; j++)
  593.                 b[m+j]=garbage(); /* fill block with trash  */
  594.             nsave += 8-m;   /* complete the block        */
  595.             }
  596.             else j=0;       /* number of nulls in last block*/
  597.             endes(b,b);    /* don't need diff input, output*/
  598.         }
  599.         else            /* decrypting            */
  600.         {   if (m < 8) deout(b, 1); /* last byte in file: count */
  601.             else
  602.             {   dedes(b, b); /* decrypt and output block    */
  603.             deout(b, 0);
  604.             }
  605.         }
  606.         }
  607.         if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave)
  608.             return(-1);
  609.     }
  610.     /* have now encrypted/decrypted the whole file;
  611.      * need to append the byte count for the last block if encrypting.
  612.      */
  613.     if (encrypting) fputc(8 - j, outfile);  /* how many good bytes? */
  614.     return(0);
  615. }
  616.  
  617. int outcount = 0;            /* see when caught up with delay*/
  618.  
  619. deout(block,flag)            /* 1-block delay on output    */
  620. char *block,flag;            /* 64-bit block, last block flag*/
  621. {    static char last[8];        /* previous input block        */
  622.     register int i;
  623. /*    register char *c,*j;    */    /* rwo: unused    */
  624.  
  625.     if (flag)            /* output the last few bytes    */
  626.     {
  627.         fwrite(last, 1, block[0] & 0377, outfile);
  628.         return;
  629.     }
  630.     if (outcount++)            /* seen any blocks before?    */
  631.         fwrite(last, 1, 8, outfile);
  632.     for (i = 0; i < 8; i++) last[i] = block[i]; /* copy the block   */
  633. }
  634.  
  635. garbage()                /* generate garbage for filling */
  636. /* This garbage should be as random as possible.  The Lattice version calls
  637.  * a somewhat sophisticated random number generator with an internal seed.
  638.  * The non-Lattice version repeatedly calls the system timer.            
  639.  */
  640. {
  641. #ifdef LATTICE
  642.     long lrand48(), ltime;
  643.  
  644.     ltime = lrand48();
  645.     return (int) ltime & 0377;
  646. #else
  647.     struct timeb tp;
  648.  
  649.     ftime(&tp);            /* get current time        */
  650.     return tp.millitm;        /* return time in milliseconds  */
  651. #endif
  652. }
  653.  
  654. #ifndef LATTICE
  655.  
  656. /* restore echo to tty and exit */
  657. bye()
  658. {
  659.     ttybuf.sg_flags |= ECHO;  /* restore echoing */
  660.     stty(0, &ttybuf);
  661.     exit(2);
  662. }
  663.  
  664. #endif
  665.  
  666. #else       /* validation */
  667.  
  668. #define VALFILE "valid.triples"
  669.  
  670. FILE *fd;
  671.  
  672. char key[8], plain[8], cipher[8], processed[8];
  673.  
  674. main()  /* read key/plain/cipher triples until exhausted */
  675. {    int count, i;
  676.  
  677.     if ((fd = fopen(VALFILE, "r")) == NULL)
  678.     {    fprintf(stderr, "Can't read %s.\n", VALFILE);
  679.         exit(1);
  680.     }
  681.     count = 0;
  682.     desinit(key);        /* initialize most of the arrays */
  683.     while (readvals())
  684.     {    kinit(key);    /* initialize key stuff        */
  685.         printf("Key: "); writehex(key);
  686.         printf("  Plain: "); writehex(plain);
  687.         printf("  Cipher: "); writehex(cipher);
  688.         printf("\n");
  689.         endes(plain, processed); /* encipher the plaintext */
  690.         printf("Encry:  "); writehex(processed);
  691.         printf("\n");
  692.         for (i = 0; i < 8; i++)
  693.             if (processed[i] != cipher[i])
  694.                 printf("Encryption failed.\n");
  695.         dedes(cipher, processed); /* decipher the ciphertext */
  696.         printf("Decry:  "); writehex(processed);
  697.         printf("\n");
  698.         for (i = 0; i < 8; i++)
  699.             if (processed[i] != plain[i])
  700.                 printf("Decryption failed.\n");
  701.         count++;
  702.     }
  703.     printf("Processed %d tests.\n", count);
  704. }
  705.  
  706. readvals()    /* get the next legit triple */
  707. {    int r;
  708.  
  709.     r = readhex(key);
  710.     readhex(plain);
  711.     readhex(cipher);
  712.     return r;
  713. }
  714.  
  715. writehex(str)   /* write the 64-bit hex string */
  716. char *str;
  717. {    int i;
  718.  
  719.     for (i = 0; i < 8; i++)
  720.         printf("%02x", str[i] & 0377);
  721. }
  722.  
  723. hex(n)  /* convert hex nibble into integer */
  724. int n;
  725. {
  726.     if (n >= 'A' && n <= 'F') return n - 'A' + 10;
  727.     return n - '0';
  728. }
  729.  
  730. readhex(str)    /* read 64 bits of hex code */
  731. char *str;
  732. {    int i, c;
  733.  
  734.     for (i = 0; i < 8; i++)
  735.     {    c = hex(getc(fd)) << 4;
  736.         str[i] = c | hex(getc(fd));
  737.     }
  738.     while ((c = getc(fd)) == ' ' || c == '\t' || c == '\n');
  739.     ungetc(c, fd);  /* skip to next field */
  740.     return c != EOF;
  741. }
  742.  
  743. #endif
  744.  
  745. /************ end scrydes ************/
  746. 
  747.